#include "CCTransform.h"
#include "cocos2d.h"
#include "CCSpineGlobal.h"


using namespace CCSpineGlobal;

CCTransform::CCTransform() {
}

CCTransform::~CCTransform() {
}

void CCTransform::Interpolator::set(float cp1X, float cp1Y, float cp2X, float cp2Y) {
    static float subdiv_step = 1.0f / _SEGMENTS_NUM;
    static float subdiv_step2 = subdiv_step * subdiv_step;
    static float subdiv_step3 = subdiv_step2 * subdiv_step;
    float pre1 = 3 * subdiv_step;
    float pre2 = 3 * subdiv_step2;
    float pre4 = 6 * subdiv_step2;
    float pre5 = 6 * subdiv_step3;
    float tmp1x = -cp1X * 2 + cp2X;
    float tmp1y = -cp1Y * 2 + cp2Y;
    float tmp2x = (cp1X - cp2X) * 3 + 1;
    float tmp2y = (cp1Y - cp2Y) * 3 + 1;
    
    dfx = cp1X * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
    dfy = cp1Y * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
    ddfx = tmp1x * pre4 + tmp2x * pre5;
    ddfy = tmp1y * pre4 + tmp2y * pre5;
    dddfx = tmp2x * pre5;
    dddfy = tmp2y * pre5;
}

float CCTransform::getInterpolationTime(float startTime, float endTime, float curTime,const Interpolator& interpolator) {
	switch(interpolator.type) {
		case LINEAR:
		{
			float t = (curTime - startTime) / (endTime - startTime);
			return t;
		}
		case BEZIER:
		{
			float percent = (curTime - startTime) / (endTime - startTime);
            float dfx = interpolator.dfx;
            float dfy = interpolator.dfy;
            float ddfx = interpolator.ddfx;
            float ddfy = interpolator.ddfy;
            float dddfx = interpolator.dddfx;
            float dddfy = interpolator.dddfy;
            float x = dfx;
            float y = dfy;
            int i = _SEGMENTS_NUM - 2;

            while (1) {
                if (x >= percent) {
                    float lastX = x - dfx;
                    float lastY = y - dfy;
                    return lastY + (y - lastY) * (percent - lastX) / (x - lastX);
                }
                if (i == 0) break;
                i--;
                dfx += ddfx;
                dfy += ddfy;
                ddfx += dddfx;
                ddfy += dddfy;
                x += dfx;
                y += dfy;
            }
            return y + (1 - y) * (percent - x) / (1 - x);
		}
		case STEP:
			return curTime >= endTime ? 1.0f : 0.0f;
		default:
			return 0;
	}
}


